package com.ckjw.gobang.connect;

import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.ResourceBundle.Control;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JOptionPane;

import com.ckjw.gobang.data.GameCenter;
import com.ckjw.gobang.data.Player;
import com.ckjw.gobang.data.Spot;
import com.ckjw.gobang.data.TableData;
import com.ckjw.gobang.utils.Coordinate;
import com.ckjw.gobang.utils.settimer;
import com.ckjw.gobang.view.ChessBroad;
import com.ckjw.gobang.view.ControlPanel;
import com.ckjw.gobang.view.MainInterface;
import com.ckjw.gobang.view.MyMenuBar;
import com.ckjw.gobang.view.UserPanel;
import com.ckjw.gobang.view.UserPanel2;
import com.ckjw.gobang.view.usertx;

/**
 * 和服务器通信线程，若没有收到服务器消息，此线程不会执行任何操作
 * 
 * @author lck and djw
 * @Date 2022年6月13日-上午10:37:49
 */
public class ClientConnectServerThread extends Thread {
	// 该线程需要持有Socket
	private Socket socket;

	// 构造器可以接受一个Socket对象
	public ClientConnectServerThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		// 因为Thread需要在后台和服务器通信，因此我们while循环
		while (true) {
	
			try {
				System.out.println("客户端线程，等待从读取从服务器端发送的消息");
				ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
				// 如果服务器没有发送Message对象,线程会阻塞在这里
				Message message = (Message) ois.readObject();
				// 注意，后面我们需要去使用message
				// 判断这个message类型，然后做相应的业务处理
				// 如果是读取到的是 服务端返回的在线用户列表
				if (message.getMesType().equals(MessageType.MESSAGE_RET_ONLINE_FRIEND)) {
					// 取出在线列表信息，并显示
					// 规定
					System.out.println("有回复");
					String users[] = message.getContent().split("\n");
					UserClientService.onlineusers.clear();
					for (int i = 0; i < users.length; i++) {
						String tmp[] = users[i].split(" ");
						UserClientService.onlineusers.put(tmp[0], tmp[1]);
					}
					// 显示在线用户
					showUser();
				} else if (message.getMesType().equals(MessageType.MESSAGE_COMM_MES)) {// 普通信息
					//获取棋子的位置以及最后坐标，并将棋子绘制出来
					String content = message.getContent();
					String tmp[] = content.split("\n");// 依次为lastx,lasty,x,y
					ChessBroad.lastx = Integer.parseInt(tmp[0]);
					ChessBroad.lasty = Integer.parseInt(tmp[1]);
					Spot spot = new Spot(Integer.parseInt(tmp[2]), Integer.parseInt(tmp[3]), TableData.getNowColor());
					TableData.putDownChess(spot);
					ChessBroad.myBroad2.repaint();
					// 检查游戏是否结束
					if (TableData.isOver()) {
						ChessBroad.aferWin();
					}
	
				} else if (message.getMesType().equals(MessageType.MESSAGE_FILE_MES)) {// 如果是文件消息
					// 让用户指定保存路径。。。
					System.out.println("\n" + message.getSender() + " 给 " + message.getGetter() + " 发文件: "
							+ message.getSrc() + " 到我的电脑的目录 " + message.getDest());
	
					// 取出message的文件字节数组，通过文件输出流写出到磁盘
					FileOutputStream fileOutputStream = new FileOutputStream(message.getDest(), true);
					fileOutputStream.write(message.getFileBytes());
					fileOutputStream.close();
					System.out.println("\n 保存文件成功~");
	
				} else if (message.getMesType().equals(MessageType.MESSAGE_GAME)) {// 游戏请求
					if (GameCenter.isEnd()) {
					String id = message.getSender();// 得到发送者
					ObjectOutputStream oos;
					oos = new ObjectOutputStream(socket.getOutputStream());
					message.setGetter(id);// 原本getter是自己现在换成对方
					message.setMesType(MessageType.MESSAGE_GAMRES);// 信息类型换为结果型
					// 显示提示框
					int res = JOptionPane.showConfirmDialog(MainInterface.mainInterface, id + "向您发送游戏请求是否同意？", "提示消息",
							JOptionPane.INFORMATION_MESSAGE);
					// 获取结果并写道message里面
					if (res == JOptionPane.YES_OPTION) {
						// 被挑战者同意后确定自己是否先行
						String a = message.getContent();// 随机数为1被挑战者先行
						if (a.equals("1")) {
							ChessBroad.firstdown = true;
						}
						// 将成功请求1写道message里面
						message.setContent("1");
						//显示到面板
						setpkinfonet(id);
						// 发送Message对象，向服务端发送结果
						oos.writeObject(message);
						// 如果同意就设置游戏模式为网络模式，执行网络开始游戏函数
						GameCenter.setMode(GameCenter.MODE_ONLINE);
						//开启定时器线程
						new settimer().start();
						afteragree();// 同意后的设置
					} else {
						message.setContent("0");// 失败
						oos.writeObject(message);
					}
				}else {
					String id = message.getSender();// 得到发送者
					ObjectOutputStream oos;
					oos = new ObjectOutputStream(socket.getOutputStream());
					message.setGetter(id);// 原本getter是自己现在换成对方
					message.setMesType(MessageType.MESSAGE_GAMRES);// 信息类型换为结果型
					message.setContent("2");//正在游戏中
					// 发送Message对象，向服务端发送结果
					oos.writeObject(message);
				}
				
					
				} else if (message.getMesType().equals(MessageType.MESSAGE_GAMRES)) {// 请求结果
					String res = message.getContent();// 0,拒绝1，接受
					if (res.equals("1")) {// 同意
						//显示对战用户信息到面板
						setpkinfoloc();
						// 如果同意就设置游戏模式为网络模式，执行网络开始游戏函数
						GameCenter.setMode(GameCenter.MODE_ONLINE);
						//开启定时器线程
						new settimer().start();
						// 执行同意请求函数
						afteragree();
					} else if (res.equals("2")) {//正在游戏中
						JOptionPane.showMessageDialog(MainInterface.mainInterface, "对方正在游戏中，请稍候尝试", "提示消息",
								JOptionPane.INFORMATION_MESSAGE);
						ChessBroad.firstdown=false;
					}
					else {// 拒绝
						JOptionPane.showMessageDialog(MainInterface.mainInterface, "对方拒绝", "提示消息",
								JOptionPane.INFORMATION_MESSAGE);
						ChessBroad.firstdown=false;
					}
				}else if (message.getMesType().equals(MessageType.MESSAGE_GAMEOVER)) {//收到游戏结束请求
					JOptionPane.showMessageDialog(MainInterface.mainInterface, "对方退出，您获胜", "提示消息",
							JOptionPane.INFORMATION_MESSAGE);
					GameCenter.reStart();
					ChessBroad.myBroad2.repaint();
					ControlPanel.localgame.setEnabled(true);
					ControlPanel.netgame.setEnabled(true);
				} 
				else {
					System.out.println("是其他类型的message, 暂时不处理....");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	
	/**
	 * 被挑战者同意后设置对战用户信息并显示到面板
	 */
	public void setpkinfonet(String id)
	{
		Player.onlinepkUser=new User();
		//设置对战用户的id
		Player.onlinepkUser.setUserId(id);
		//设置姓名
		Player.onlinepkUser.setName(UserClientService.onlineusers.get(id));
		//设置棋色
		if (ChessBroad.firstdown) {
			Player.onlinepkUser.setClor(Spot.whiteChess); 
			Player.onlineuser.setClor(Spot.blackChess); 
		} else {
			Player.onlinepkUser.setClor(Spot.blackChess); 
			Player.onlineuser.setClor(Spot.whiteChess); 
		}
		//显示到界面上
		UserPanel2.textField_3.setText(" 用户名："+Player.onlinepkUser.getName());
		UserPanel2.textField_4.setText("      I D ："+id);
		if (Player.onlinepkUser.clor.equals(Spot.blackChess)) {
			UserPanel2.textField_2.setText("   棋色  ："+"白棋");
			UserPanel2.textField_5.setText("   棋色  ："+"黒棋");
		} else {
			UserPanel2.textField_2.setText("   棋色  ："+"黑棋");
			UserPanel2.textField_5.setText("   棋色  ："+"白棋");
		}
		
	}
	/**
	 * 挑战者接受到同意请求后设置对战用户信息并显示到面板
	 */
	public void setpkinfoloc()
	{
		Player.onlinepkUser=new User();
		//设置对战用户的id
		Player.onlinepkUser.setUserId(UserPanel2.selectUsertx.getId());
		//设置姓名
		Player.onlinepkUser.setName(UserClientService.onlineusers.get(Player.onlinepkUser.getUserId()));
		//设置棋色
			if (ChessBroad.firstdown) {
				Player.onlinepkUser.setClor(Spot.whiteChess); 
				Player.onlineuser.setClor(Spot.blackChess); 

			} else {
				Player.onlinepkUser.setClor(Spot.blackChess); 
				Player.onlineuser.setClor(Spot.whiteChess); 

			}
		//显示到界面上
		UserPanel2.textField_3.setText(" 用户名："+Player.onlinepkUser.getName());
		UserPanel2.textField_4.setText("      I D ："+Player.onlinepkUser.getUserId());
		if (Player.onlinepkUser.clor.equals(Spot.blackChess)) {
			UserPanel2.textField_2.setText("   棋色  ："+"白棋");
			UserPanel2.textField_5.setText("   棋色  ："+"黒棋");
		} else {
			UserPanel2.textField_2.setText("   棋色  ："+"黑棋");
			UserPanel2.textField_5.setText("   棋色  ："+"白棋");
		}
		
	}
	
	/**
	 * 同意后的操作
	 * 1.设置游戏模式为网络对战
	 * 2.设置按钮不可点击，即不可中途退出
	 * 3.显示是否先行
	 */
	public void afteragree() {
		UserPanel.userPanel.setVisible(false);
		UserPanel2.userPanel.setVisible(true);
		  // 初始化棋桌数据
        TableData.reset();
        ChessBroad.lastx=-1;
        ChessBroad.lasty=-1;
		// 游戏中不能在点击按钮
		ControlPanel.localgame.setEnabled(false);
		ControlPanel.netgame.setEnabled(false);
		// 如果为真
		if (ChessBroad.firstdown) {
			JOptionPane.showMessageDialog(MainInterface.mainInterface, "您执黒棋，您先行", "提示消息",
					JOptionPane.INFORMATION_MESSAGE);
		} else {
			JOptionPane.showMessageDialog(MainInterface.mainInterface, "您执白棋，您后行", "提示消息",
					JOptionPane.INFORMATION_MESSAGE);
		}
	}

	/**
	 * 将从服务器获取到的用户hashmap表onlineuser显示到界面上
	 */
	public void showUser() {
		System.out.println("界面显示");
		System.out.println("\n=======当前在线用户列表========");
		int j = 0;
		UserPanel2.panel_1.removeAll();
		Player.onlineuser.setName(UserClientService.onlineusers.get(Player.onlineuser.getUserId()));
		MyMenuBar.wel.setText("欢迎您：" + Player.onlineuser.getName());
		UserPanel2.textField_1.setText(" 用户名："+Player.onlineuser.getName());
		UserPanel2.txtId.setText("      I D ："+Player.onlineuser.getUserId());
		UserClientService.onlineusers.remove(Player.onlineuser.getUserId());
		for (String i : UserClientService.onlineusers.keySet()) {
			UserPanel2.panel_1.add(new usertx(i, UserClientService.onlineusers.get(i)));
			int hig = j * 50 + 5;
			usertx.usertx2.setBounds(0, hig, 190, 50);
			System.out.println("key: " + i + " value: " + UserClientService.onlineusers.get(i));
			j++;
		}
		UserPanel2.panel_1.repaint();
		UserPanel2.userPanel.repaint();
		MainInterface.mainInterface.repaint();
	}

	// 为了更方便的得到Socket
	public Socket getSocket() {
		return socket;
	}
}
